package winOrDie.Net.Server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

/**
 * This public class is the socket server. Listens on tcp port and manage new sockets.
 */
public class WoD_TCP_Socket_Server implements Runnable 
{
	
	/**
	 * Internal variable to stop this thread.
	 */
	private boolean fIsStopRequested = false;
	

	
	private ServerSocket serverSocket;
	private int port_TCP_CONTROL;
	
	private Vector<WoD_TCP_Socket_Server_Listener> listeners = null;
	

	public WoD_TCP_Socket_Server(int port_TCP_CONTROL) 
	{

		this.port_TCP_CONTROL = port_TCP_CONTROL;
		listeners = new Vector<WoD_TCP_Socket_Server_Listener>();
	}
	
	
	
	public synchronized void add_WoD_TCP_Socket_Server_Listener(WoD_TCP_Socket_Server_Listener listener)
	{
		listeners.add(listener);
	}
	
	public synchronized void remove_WoD_TCP_Socket_Server_Listener(WoD_TCP_Socket_Server_Listener listener)
	{
		listeners.remove(listener);
	}
	
	protected void fireEvent(WoD_TCP_Socket_Server_Event event)
	{
		for (WoD_TCP_Socket_Server_Listener listener : listeners) {
			listener.notify_Event_WoD_TCP_Socket_Server(event);
		}
	}
	
	
	public void start_Server() throws Exception
	{
		try {
			/*
			 * Server notification 
			 */
			WoD_TCP_Socket_Server_Event event = new WoD_TCP_Socket_Server_Event(this);
			event.setEvent_Type(WoD_TCP_Socket_Server_Event.SERVER_STARTING);
			fireEvent(event);
			serverSocket = new ServerSocket(port_TCP_CONTROL);
		} catch (IOException e) {
			Exception exception = new Exception("Error triying to listening on port " + port_TCP_CONTROL + ". " + e.getMessage());
			throw exception;
		}
		WoD_TCP_Socket_Server_Event event = new WoD_TCP_Socket_Server_Event(this);
		event.setEvent_Type(WoD_TCP_Socket_Server_Event.SERVER_INITIALICED);
		fireEvent(event);
		
	}
	
	@Override
	public void run() {
		
		while (!fIsStopRequested) {
			Socket socket = null;
			try {
				/*
				 * Wait for another connection
				 */
				socket = serverSocket.accept();
			} catch (IOException e) {
				
				/*
				 * Error notification
				 */
				WoD_TCP_Socket_Server_Event event = new WoD_TCP_Socket_Server_Event(this);
				event.setEvent_Type(WoD_TCP_Socket_Server_Event.SERVER_ERROR);
				String error = "Error de IO. " + e.getMessage();
				event.setData(error);
				fireEvent(event);
			}
			
			if (socket != null)
			{
				/*
				 * Client notification
				 */
				WoD_TCP_Socket_Server_Event event = new WoD_TCP_Socket_Server_Event(this);
				event.setEvent_Type(WoD_TCP_Socket_Server_Event.NEW_CLIENT);
				event.setData(socket);
				fireEvent(event);
			}
			
		}
	}
	
	

}


